package com.shf.lease.web.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shf.lease.entity.*;
import com.shf.lease.enums.ItemType;
import com.shf.lease.enums.LeaseStatus;
import com.shf.lease.exception.BizException;
import com.shf.lease.result.Result;
import com.shf.lease.result.ResultCodeEnum;
import com.shf.lease.web.admin.controller.apartment.query.QueryApartmentParams;
import com.shf.lease.web.admin.controller.apartment.request.ApartmentCmd;
import com.shf.lease.web.admin.controller.apartment.request.GraphCmd;
import com.shf.lease.web.admin.controller.apartment.response.*;
import com.shf.lease.web.admin.mapper.*;
import com.shf.lease.web.admin.service.*;
import jakarta.annotation.Resource;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 叶枫
* @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
* @createDate 2024-07-05 16:43:45
*/
@Service
@Transactional
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
    implements ApartmentInfoService{

    @Resource
     private LeaseAgreementService leaseAgreementService;

    @Resource
    private RoomInfoService roomInfoService;
    /**图片接口*/
    @Resource
    private GraphInfoService graphInfoService;
    /**公寓&配套接口*/
    @Resource
    private ApartmentFacilityService apartmentFacilityService;
    /**公寓&标签接口*/
    @Resource
    private ApartmentLabelService apartmentLabelService;
    /**公寓&杂费*/
    @Resource
    private ApartmentFeeValueService apartmentFeeValueService;
    @Resource
    private FacilityInfoMapper facilityInfoMapper;
    @Resource
    private LabelInfoMapper labelInfoMapper;
    @Resource
    private GraphInfoMapper graphInfoMapper;
    @Resource
    private FeeValueMapper feeValueMapper;



    @Override
    public Result<PageListVo<PageListApartmentVo>> queryPageListApartment(QueryApartmentParams queryParams) {

        LambdaQueryWrapper<ApartmentInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(queryParams.getDistrictId() != null, ApartmentInfo::getDistrictId, queryParams.getDistrictId())
                .eq(queryParams.getProvinceId() != null, ApartmentInfo::getProvinceId, queryParams.getProvinceId())
                .eq(queryParams.getCityId() != null, ApartmentInfo::getCityId, queryParams.getCityId());

        Page<ApartmentInfo> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        Page<ApartmentInfo> apartmentInfoPage = page(page, queryWrapper);
        List<PageListApartmentVo> collect = apartmentInfoPage.getRecords().stream().map(new Function<ApartmentInfo, PageListApartmentVo>() {
            @Override
            public PageListApartmentVo apply(ApartmentInfo apartmentInfo) {
                PageListApartmentVo apartmentVo = convert(apartmentInfo);

                return spareRoomNum(apartmentVo);
            }
        }).collect(Collectors.toList());

        PageListVo<PageListApartmentVo> resultVo = new PageListVo<>();
        resultVo.setRecourds(collect);
        resultVo.setTotal( apartmentInfoPage.getTotal());
        resultVo.setPageNum(queryParams.getPageNum());
        resultVo.setPageSize(queryParams.getPageSize());

        return Result.ok(resultVo);

    }

    @Override
    public Result saveOrUpdateApartment(ApartmentCmd request) {
        //添加基本信息或者修改任意信息
        super.saveOrUpdate(request);
        if (request.getId()!=null){
            //删除 图片联系表的信息
            graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemId,request.getId())
                    .eq(GraphInfo::getItemType, ItemType.APARTMENT));

            //删除公寓配套关系
            apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().eq(ApartmentFacility::getApartmentId,request.getId()));
            //删除公寓标签关系
            apartmentLabelService.remove(new LambdaQueryWrapper<ApartmentLabel>().eq(ApartmentLabel::getApartmentId,request.getId()));

        }

        //插入 或更新 图片信息
        List<GraphInfo> collect = request.getGraphVoList().stream().map(graphCmd -> {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setItemType(ItemType.APARTMENT);
            graphInfo.setName(graphCmd.getName());
            graphInfo.setItemId(request.getId());
            graphInfo.setUrl(graphCmd.getUrl());
            return graphInfo;

        }).collect(Collectors.toList());
        graphInfoService.saveBatch(collect);

        //插入公寓配套信息
        List<ApartmentFacility> facilityList = request.getFacilityInfoIds().stream()
                .map(aLong -> {
                    ApartmentFacility apartmentFacility = new ApartmentFacility();
                    apartmentFacility.setApartmentId(request.getId());
                    apartmentFacility.setFacilityId(aLong);
                    return apartmentFacility;
                }).collect(Collectors.toList());
        apartmentFacilityService.saveBatch(facilityList);
        //插入公寓标签信息
        List<ApartmentLabel> labelList = request.getLabelIds().stream()
                .map(aLong -> {
                    ApartmentLabel apartmentLabel = new ApartmentLabel();
                    apartmentLabel.setApartmentId(request.getId());
                    apartmentLabel.setLabelId(aLong);
                    return apartmentLabel;
                }).collect(Collectors.toList());
        apartmentLabelService.saveBatch(labelList);
        //插入公寓杂费信息
        List<ApartmentFeeValue> feeValueList = request.getFeeValueIds().stream()
                .map(feeValueCmdId -> {
                    ApartmentFeeValue apartmentFeeValue = new ApartmentFeeValue();
                    apartmentFeeValue.setApartmentId(request.getId());
                    apartmentFeeValue.setFeeValueId(feeValueCmdId);
                    return apartmentFeeValue;
                }).collect(Collectors.toList());
        apartmentFeeValueService.saveBatch(feeValueList);

        return Result.ok();

    }

    @Override
    public Result<ApartmentDetailVo> getDetailById(Long id) {
        if (id == null){
            throw new BizException("传入参数不能为空");
        }
        ApartmentInfo apartmentInfo = this.getById(id);
        if (apartmentInfo == null){
            return Result.fail("查询不到公寓");
        }
        ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo();
        BeanUtils.copyProperties(apartmentInfo,apartmentDetailVo);
        //查询公寓配套列表
       List<FacilityInfo> facilityInfoList =  facilityInfoMapper.selectListByItemTypeAndId(ItemType.APARTMENT,id);
       //查询图片列表
        List<GraphVo> graphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.APARTMENT,id);
        //查询公寓标签列表
        List<LabelInfo> labelInfoList = labelInfoMapper.selectByItemTypeAndId(ItemType.APARTMENT,id);
        //查询公寓杂费列表
        List<FeeValueVo> feeValueVoList = feeValueMapper.selectListById(id);
        apartmentDetailVo.setFacilityInfoList(facilityInfoList);
        apartmentDetailVo.setGraphList(graphVoList);
        apartmentDetailVo.setFeeValueVoList(feeValueVoList);
        apartmentDetailVo.setLabelList(labelInfoList);
        return Result.ok(apartmentDetailVo);
    }

    @Override
    public Result deleteApartment(Long id) {
    //判断当前公寓下是否有房间
        LambdaQueryWrapper<RoomInfo> roomQueryWrapper = new LambdaQueryWrapper<>();
        roomQueryWrapper.eq(RoomInfo::getApartmentId, id);
        Long count = roomInfoService.count(roomQueryWrapper);
        if (count > 0) {
            throw new BizException(ResultCodeEnum.ADMIN_APARTMENT_DELETE_ERROR);
        }
        //1.删除GraphInfo
        LambdaQueryWrapper<GraphInfo> graphQueryWrapper = new LambdaQueryWrapper<>();
        graphQueryWrapper.eq(GraphInfo::getItemType, ItemType.APARTMENT);
        graphQueryWrapper.eq(GraphInfo::getItemId, id);
        graphInfoService.remove(graphQueryWrapper);

        //2.删除ApartmentLabel
        LambdaQueryWrapper<ApartmentLabel> labelQueryWrapper = new LambdaQueryWrapper<>();
        labelQueryWrapper.eq(ApartmentLabel::getApartmentId, id);
        apartmentLabelService.remove(labelQueryWrapper);

        //3.删除ApartmentFacility
        LambdaQueryWrapper<ApartmentFacility> facilityQueryWrapper = new LambdaQueryWrapper<>();
        facilityQueryWrapper.eq(ApartmentFacility::getApartmentId, id);
        apartmentFacilityService.remove(facilityQueryWrapper);

        //4.删除ApartmentFeeValue
        LambdaQueryWrapper<ApartmentFeeValue> feeQueryWrapper = new LambdaQueryWrapper<>();
        feeQueryWrapper.eq(ApartmentFeeValue::getApartmentId, id);
        apartmentFeeValueService.remove(feeQueryWrapper);

        //5.删除ApartmentInfo
        super.removeById(id);
        return Result.ok();
    }

    /**
     * 转换
     * @param apartmentInfo
     * @return
     */
    private PageListApartmentVo convert(ApartmentInfo apartmentInfo) {
        PageListApartmentVo apartmentVo = new PageListApartmentVo();
        apartmentVo.setId(apartmentInfo.getId());
        apartmentVo.setName(apartmentInfo.getName());
        apartmentVo.setPhone(apartmentInfo.getPhone());
        apartmentVo.setAddressDetail(apartmentInfo.getAddressDetail());
        apartmentVo.setCityName(apartmentInfo.getCityName());
        apartmentVo.setProvinceName(apartmentInfo.getProvinceName());
        apartmentVo.setDistrictName(apartmentInfo.getDistrictName());
        apartmentVo.setIsRelease(apartmentInfo.getIsRelease());

        return apartmentVo;
    }

    /**
     * 计算 总房间 和可用房间
     * @param listApartmentVo
     * @return
     */
    private PageListApartmentVo spareRoomNum(PageListApartmentVo listApartmentVo){
        LambdaQueryWrapper<RoomInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(listApartmentVo.getId() != null, RoomInfo::getApartmentId, listApartmentVo.getId())
                .select(RoomInfo::getId);
        List<RoomInfo> roomInfos = roomInfoService.list(queryWrapper);
        int roomCount = roomInfos.size();

        Set<Long> roomIds = roomInfos.stream().map(roomInfo -> roomInfo.getId())
                .collect(Collectors.toSet());

        //查询已经绑定的租约
        LambdaQueryWrapper<LeaseAgreement> queryWrapper1 = new LambdaQueryWrapper<>();

        queryWrapper1.in(LeaseAgreement::getRoomId,roomIds)
                .in(LeaseAgreement::getStatus, LeaseStatus.SIGNED, LeaseStatus.WITHDRAWING);
        long signCount = leaseAgreementService.count(queryWrapper1);
        int spareRoomNum = roomCount - (int)signCount;
        listApartmentVo.setSpareRoomNum(spareRoomNum);
        listApartmentVo.setRoomNum(roomCount);

        return listApartmentVo;

    }
}




